package Thread;


class MyBlockingQueue{
    private  String[] elems = null;  // 用来存储元素

    private  int head = 0; // 定义队首指针

    private int tail = 0; // 定义队尾指针

    private int size = 0; // 定义当前有多少个元素

    private Object locker = new Object();
    public MyBlockingQueue(int capacity){
        // 构造方法
        elems = new String[capacity];
    }

    public void put (String elem) throws InterruptedException {
        synchronized (locker){  //加上锁
            while (size >= elems.length){
                // 队列已满, 此时需要阻塞, 不能在插入元素了
                // 使用wait来阻塞
                // 注意这里为什么使用while 来进行循环判断
                locker.wait();
            }
            elems[tail] = elem;
            tail=tail+1;
            if (tail >= elems.length){
                // 满了tail回到队首
                tail=0;
            }
            size= size+1;
            locker.notify();
        }
    }

    public String take() throws InterruptedException {
        String ele = null;
        synchronized (locker){
            while (size == 0){
                //此时队列为空, 想要移除元素, 就需要阻塞
                locker.wait();
            }
            ele = elems[head];
            head= head+1;
            if (head >=elems.length){
                head=0;
            }
            size=size-1;
            locker.notify();
        }
        return ele;
    }

}
public class ThreadDemo5 {
    public static void main(String[] args) throws InterruptedException {
        MyBlockingQueue queue = new MyBlockingQueue(100);
//        queue.put("aaa");
//        queue.put("bbb");
//        queue.put("ccc");
//
//        String ele = "";
//        ele = queue.take();
//        System.out.println("elem = "+ ele);
//        queue.take();
//        System.out.println("elem = "+ ele);
//        queue.take();
//        System.out.println("elem = "+ ele);


        // 通过线程来演示
        // 这是生产者
        Thread t1 = new Thread(()->{
            int n = 1;
            while (true){
//                try {
//                    Thread.sleep(1000);
//                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                }
                try {
                    queue.put(n+"");
                    System.out.println("生产元素" + n);
                    n++;

                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        // 这是消费者
        Thread t2 = new Thread(()->{
           while (true){

               try {
                   String ele = queue.take();
                   System.out.println("消费元素" + ele);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
           }
        });

        t1.start();
        t2.start();
    }
}
